/**
 * Created by hjqi on 2017/2/6.
 */

var base = require('./storageBase');
var util = require('util');
var Common = require('../common/common');
var myRet = Common.myReturn;
var emptyPromise = Common.emptyPromise;
var logger = require('../log4js/log4js').logger('cephRrd');
var formurlencoded = require('form-urlencoded');
var httpRequest = require('../common/httpRequest').httpRequest;
var _req = new httpRequest();
var config = require('../config/config').config;
var _restapi = config.ceph_restful_api;
var storageMetaInfoDB = require('../../db/storageMetaInfoDB');


module.exports = libCephRbd;

function libCephRbd(){
    base.call(this);
}

/**
 * create storage endpoint in k8s and create volume
 * @param   {String}    ns     = namespace in k8s
 * @param   {String}    vol    = volume object {mountName: xxx,  volumeName:xxx }
 */
libCephRbd.prototype.createVolume = function(ns,vol,policy){
    var self = this;
    var _k8s_adp = require('../k8s/k8sAdpter');
    return new Promise(function (resolve, reject) {
        _k8s_adp.getK8s('default').then(function(_k8s){
            return _k8s.createCephSecrectInOwnNS(ns);
        }).then(function() {
            return _createPoolInOwnNS(ns);
        }).then(function(){
            return self.createVolumeImpl(ns,vol,policy);
        }).then(function(ret){
            //successful
            resolve(ret);
        }).catch(function(err){
            //exception
            var errdata=err.message||err.error;
            reject(myRet(false,errdata));

        })
    });
}

/**
 * delete volume request
 * @param   {String}    ns     = namespace in k8s
 * @param   {String}    volume    = volume object
 */
libCephRbd.prototype.deleteVolume = function(volume){
    var _url = "http://" + _restapi.host + ":" + _restapi.port + "/rados/rbd/removeImg.do";
    var _self = this;
    return new Promise(function (resolve, reject) {
        _operatorVolume(volume.namespace,volume.volumeId,_url).then(function(ret){
            if(ret.ret === true){
                return _self.DelInfoFromDB(volume.namespace,volume.volumeId);
            }else {
                throw ret;
            }
        }).then(function(ret){
            resolve(ret);
        }).catch(function(err){
            reject(err);
            var isInclude = err.error.indexOf("No such file or directory");
            if(isInclude > 0){
                logger.debug("delete info from DB!")
                return _self.DelInfoFromDB(volume.namespace,volume.volumeId);
            }
        });
    });
}

/**
 * create volume request
 * @param   {String}    ns     = namespace in k8s
 * @param   {String}    volumeId    = volume id  (namespaces-volumename)
 */
libCephRbd.prototype.createVolumeReq = function(ns,volumeId,size){
    var _url = "http://" + _restapi.host + ":" + _restapi.port + "/rados/rbd/createImg.do";
    return _operatorVolume(ns,volumeId,_url,size);
}

/**
 * check if volume id exist in volume servers
 * @param   {String}    volumeId    = volume id  (namespaces-volumename)
 * @param   {String}    ns     = namespace in k8s
 */
libCephRbd.prototype.isExistVolumeInServer = function(volumeId,ns){
    return new Promise(function (resolve, reject) {
        /**
         *  list volume id from volume server, and check volume id if exist
         *  if error happened, reject it
         */
        _listVolumes(ns).then(function(ret){
            if(ret.ret === true){
                if(ret.data instanceof  Array && ret.data.indexOf(volumeId) !== -1)
                    resolve(myRet(true));
                else
                    resolve(myRet(false));
            }else
                reject(ret);

        }).catch(function(err){
            reject(err);
        });
    });
}

/**
 * create pool in volume servers , use ns as pool name
 * @param   {String}    ns     = namespace in k8s
 */
function _createPoolInOwnNS(ns){
    var _url = "http://" + _restapi.host + ":" + _restapi.port + "/rados/rbd/create.do";
    return new Promise(function(resolve, reject){
        _operatorPool(ns,_url).then(function(ret){
            resolve(ret);
        }).catch(function(err){
            if(err.error.indexOf("File exists") !== -1){
                resolve(myRet(true));
            }else
                reject(err);
        });
    });

}

/**
 * delete pool in volume servers , use ns as pool name
 * @param   {String}    ns     = namespace in k8s
 */
function _deletePoolInOwnNS(ns){
    var _url = "http://" + _restapi.host + ":" + _restapi.port + "/rados/rbd/delete.do";
    return _operatorPool(ns,_url);
}

/**
 * get image's usage
 * @param   {String}    ns     = namespace in k8s
 * @param   {String}    volume    = volume object
 * @Author  JohnnyDu <dovedudus@163.com>
 */
libCephRbd.prototype._usedImage=function(volume){
    return new Promise(function (resolve, reject) {
        var _url = "http://" + _restapi.host + ":" + _restapi.port + "/rados/rbd/getImgUsage.do";
        var _httpBasicHeader = {
            "Content-Type": 'application/json',
            "Connection":"keep-alive"
        }

        var _param = {
            imageName: volume.volumeId,
            pool: volume.namespace,
            sessionid:volume.namespace
        }
        _url += "?"+formurlencoded(_param);
        _req._request(_url,"GET",_httpBasicHeader,'',function(data, result, response){
            if (data !== null ){
                if(data instanceof Error){
                    logger.error("get iamge usage error:"+data.message);
                    reject(myRet(false,data.message));
                }else{
                    var _json = JSON.parse(data.data);
                    resolve(myRet(true,undefined,_json.data));
                }
            }
            else{
                logger.error("get iamge usage error:"+result);
                reject(myRet(false,result));
            }
        });

    });
}


/**
 * create or delete pool in volume servers
 * @param   {String}    ns     = namespace in k8s
 * @param   {String}    _url   = request operator pool url
 */
function _operatorPool(ns,_url){
    return new Promise(function (resolve, reject) {

        var _httpBasicHeader = {
            "Content-Type": 'application/json',
            "Connection":"keep-alive"
        }

        var _postData = {
            "pool":ns,
            "sessionid":ns
        };

        _req._request(_url, "POST", _httpBasicHeader, JSON.stringify(_postData) , function (data, result, response) {
            if (data !== null) {
                if(data.data === undefined)
                    console.log(data);
                else{
                    var _obj = JSON.parse(data.data);
                    if(_obj.code === "success"){
                        resolve(myRet(true));
                    }else{
                        logger.error(_obj.msg);
                        //resolve(myRet(true));
                        reject(myRet(false,_obj.msg));
                    }
                }
            }else{
                reject(myRet(false,result));
            }
        });
    });
}

/**
 * create or delete volume  in volume servers
 * @param   {String}    ns     = namespace in k8s
 * @param   {String}    volumeId     = volume Id
 * @param   {String}    _url     = request url
 */
function _operatorVolume(ns,volumeId,_url,size){
    return new Promise(function (resolve, reject) {
        var _httpBasicHeader = {
            "Content-Type": 'application/json',
            "Connection":"keep-alive"
        }

        var _postData = {
            imageName: volumeId,
            pool:ns,
            sessionid:ns,
            size:size*1024*1024
        };
        logger.debug("call operate volume ["+volumeId+"]");
        _req._request(_url, "POST", _httpBasicHeader, JSON.stringify(_postData), function (data, result, response) {
            if (data !== null) {
                if(data.data === undefined)
                    console.log(data);
                else{
                    logger.debug("req volume ["+volumeId+"] , and service return ["+data.data+"]");
                    var _obj = JSON.parse(data.data);
                    if(_obj.code === "success"){
                        resolve(myRet(true));
                    }else{
                        logger.error(_obj.msg);
                        reject(myRet(false,_obj.msg));
                    }
                }
            }else{
                reject(myRet(false,result));
            }
        });
    });
}

/**
 * list volume id  in volume servers
 * @param   {String}    ns     = namespace in k8s
 */
function _listVolumes(ns){
    return new Promise(function (resolve, reject) {
        var _url = "http://" + _restapi.host + ":" + _restapi.port + "/rados/rbd/listImg.do";
        var _httpBasicHeader = {
            "Content-Type": 'application/json',
            "Connection":"keep-alive"
        }

        var _param = {
            pool:ns,
            sessionid:ns
        }
        _url += "?"+formurlencoded(_param);
        _req._request(_url,"GET",_httpBasicHeader,'',function(data, result, response){
            if (data !== null ){
                if(data instanceof Error){
                    logger.error("get volume list error:"+data.message);
                    reject(myRet(false,data.message));
                }else{
                    var _json = JSON.parse(data.data);
                    resolve(myRet(true,undefined,_json.data));
                }
            }
            else{
                logger.error("get volume list error:"+result);
                reject(myRet(false,result));
            }
        });

    });
}

util.inherits(libCephRbd,base);